package com.yiwyn;

import com.yiwyn.domain.User;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @className: ReflectDemo
 * @author: Yiwyn
 * @date: 2025/11/23 17:19
 * @Version: 1.0
 * @description: 反射方法
 */
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 1, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@State(Scope.Benchmark)
@Fork(value = 1)
public class ReflectDemo {


    public static void main(String[] args) throws RunnerException {
        Options options = new OptionsBuilder()
                .include(ReflectDemo.class.getSimpleName())
                .build();
        new Runner(options).run();
    }

    @Benchmark
    public void step1() throws NoSuchFieldException, IllegalAccessException {
        // 用户集合
        List<User> list = new ArrayList<>();

        // 创建10w个用户，并把给手机号赋值
        for (int i = 0; i < 100_000; i++) {
            User us = new User();
            us.setPhone("" + i);
            list.add(us);
        }

        // 使用反射将手机号给用户民赋值
        for (User user : list) {
            Class<User> userClass = User.class;
            Field phone = userClass.getDeclaredField("phone");
            phone.setAccessible(true);
            Object o = phone.get(user);
            Field userName = userClass.getDeclaredField("userName");
            userName.setAccessible(true);
            userName.set(user, "用户" + o);
        }
    }


    @Benchmark
    public void step2() throws NoSuchFieldException, IllegalAccessException {
        Field phone = User.class.getDeclaredField("phone");
        phone.setAccessible(true);
        Field userName = User.class.getDeclaredField("userName");
        userName.setAccessible(true);

        for (int i = 0; i < 100000; i++) {
            // 使用反射获取值并赋值
            User user = new User();
            user.setPhone("133333333");
            Object o = phone.get(user);
            userName.set(user, o);
        }
    }


}
